import matches from 'lodash/matches'

import { BatchEvent } from '@slardar/sdk-template'

export const findAndAssert = findMultiAndAssert.bind(null, 1)

export function findMultiAndAssert(
  count: number,
  findFn: (ev: any) => boolean,
  assertFn: (ev: any) => void,
  timeout = 2000,
) {
  let data = [] as any[]
  function assert(body: BatchEvent<any>) {
    data = data.concat(body?.list?.filter(findFn) || [])
    if (data.length < count) {
      cy.wait('@post', { timeout }).its('request.body').then(assert)
    } else {
      data.forEach(assertFn)
    }
  }
  cy.wait('@post').its('request.body').then(assert)
}

export const matchAndAssert = matchMultiAndAssert.bind(null, 1)
export function matchMultiAndAssert(count: number, findObj: any, assertFn: (ev: any) => void, timeout?: number) {
  findMultiAndAssert(count, matches(findObj), assertFn, timeout)
}

export const findAndAssertAll = findMultiAndAssertAll.bind(null, 1)

export function findMultiAndAssertAll(count: number, findFn: (ev: any) => boolean, assertFn: (data: any[]) => void) {
  let data = [] as any[]
  let allData = [] as any[]
  function assert(body: BatchEvent<any>) {
    allData = allData.concat(body.list)
    data = data.concat(body?.list?.filter(findFn) || [])
    if (data.length < count) {
      cy.wait('@post', { timeout: 2000 }).its('request.body').then(assert)
    } else {
      assertFn(allData)
    }
  }
  cy.wait('@post').its('request.body').then(assert)
}
export const matchAndAssertAll = matchMultiAndAssertAll.bind(null, 1)
export function matchMultiAndAssertAll(count: number, findObj: any, assertFn: (data: any[]) => void) {
  findMultiAndAssertAll(count, matches(findObj), assertFn)
}

export function findMultiAndMatch(
  count: number,
  findFn: (ev: any) => boolean,
  matchFn: (ev: any) => boolean,
  timeout = 2000,
) {
  let data = [] as any[]
  function assert(body: BatchEvent<any>) {
    data = data.concat(body?.list?.filter(findFn).filter(matchFn) || [])
    if (data.length < count) {
      cy.wait('@post', { timeout }).its('request.body').then(assert)
    } else {
      expect(true).to.be.equal(true)
    }
  }
  cy.wait('@post').its('request.body').then(assert)
}

export const matchAndMatch = matchMultiAndMatch.bind(null, 1)

export function matchMultiAndMatch(count: number, findObj: any, matchObj: any, timeout?: number) {
  findMultiAndMatch(count, matches(findObj), matches(matchObj), timeout)
}
